﻿using System.IO;
using System.Xml;
using System;
namespace CrossPlatform
{
    public class CrossPlatformMessages
    {
        public CrossPlatformMessages()
        {
        }
        public static string CrossPlatformTestMessage = "Test of original message - then modified under common";
    }

    public class CrossPlatformMessagesForSumpPump
    {
        public CrossPlatformMessagesForSumpPump()
        {
        }

        #region Sample code of easy generic xml serialization of objects which is not supported on .netMF
#if useInvalidCode
        /// <summary>
        /// Search down to find "g.To write any object or some collections to xml" in the page noted here
        /// </summary>
        /// <see cref="http://www.fincher.org/tips/Languages/csharp.shtml"/>
        public static string SerializeToXmlString(object objectToSerialize)
        {
            MemoryStream memoryStream = new MemoryStream();
            System.Xml.Serialization.XmlSerializer xmlSerializer =
                new System.Xml.Serialization.XmlSerializer(objectToSerialize.GetType());
            xmlSerializer.Serialize(memoryStream, objectToSerialize);
            ASCIIEncoding ascii = new ASCIIEncoding();
            return ascii.GetString(memoryStream.ToArray());
        }

        public static object DeSerializeFromXmlString(System.Type typeToDeserialize, string xmlString)
        {
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(xmlString);
            MemoryStream memoryStream = new MemoryStream(bytes);
            System.Xml.Serialization.XmlSerializer xmlSerializer =
                new System.Xml.Serialization.XmlSerializer(typeToDeserialize);
            return xmlSerializer.Deserialize(memoryStream);
        }
//        Example
//[Test]
//public void GetBigList() {
//    var textRepository = ObjectFactory.GetInstance<ITextRepository>();
//    List<BrandAndCode> brandAndCodeList = textRepository.GetList(...);
//    string xml = SerializeToXmlString(brandAndCodeList);
//    Console.Out.WriteLine("xml = {0}", xml);
//     var brandAndCodeList2 = DeSerializeFromXmlString(typeof (BrandAndCode[]), xml);
//}

        public string xmlNodeToString(XmlNode sourceNode)
        {
            StringWriter stringWriter = new StringWriter();
            XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);
            xmlTextWriter.Formatting = Formatting.Indented;
            sourceNode.WriteTo(xmlTextWriter); //xmlDocument can be replaced with an XmlNode
            xmlTextWriter.Flush();
            return stringWriter.ToString();

        }
#endif
        #endregion




        public static string SumpPumpDataMessageStartString = "SumpPumpStatusMessageStart";
        public static string SumpPumpDataMessageEndString = "SumpPumpStatusMessageEnd";

        public static string SumpPumpEventMessageStartString = "SumpPumpEventMessageStart";
        public static string SumpPumpEventMessageEndString = "SumpPumpEventMessageEnd";

        public string messageRequestingSumpPumpStatusUpdate()
        {
            return "d";
        }

        public string createSumpPumpStatusMessage(int RawDistanceCentimeters, int CalibratedWaterLevelCentimeters)
        {
            string newMessage = SumpPumpDataMessageStartString
                + CrossPlatformConstants.simpleStringDelimeterForMessages
                + RawDistanceCentimeters.ToString()
                + CrossPlatformConstants.simpleStringDelimeterForMessages
                + CalibratedWaterLevelCentimeters.ToString()
                + CrossPlatformConstants.simpleStringDelimeterForMessages
                + SumpPumpDataMessageEndString;
            return newMessage;
        }

        public string parseSumpPumpStatusMessage(
            string currentMessage,
            ref bool successParsing,
            ref int RawDistanceCentimeters,
            ref int CalibratedWaterLevelCentimeters,
            bool removeParsedMessage)
        {
            string messageBufferWithMessageRemoved = currentMessage;
            successParsing = false; // default to fail

            // find start of a message (in case there are multiple messages or a partial message)
            string firstMessage = string.Empty;
            int indexOfFirstMessageStart = currentMessage.IndexOf(SumpPumpDataMessageStartString);

            // if we found a start of a message, try to parse it
            if (indexOfFirstMessageStart >= 0)
            {
                firstMessage = currentMessage.Substring(indexOfFirstMessageStart);

                // now try to find a message end that completes the first message
                int indexOfStartOfFirstMessageEndWithinFirstMessage = firstMessage.IndexOf(SumpPumpDataMessageEndString);
                if (indexOfStartOfFirstMessageEndWithinFirstMessage >= 0)
                {
                    // calculate end of message end tag within entire message buffer
                    int indexOfEndOfFirstMessageEndWithinEntireMessageBuffer = indexOfFirstMessageStart + indexOfStartOfFirstMessageEndWithinFirstMessage + SumpPumpDataMessageEndString.Length;

                    firstMessage = currentMessage.Substring(indexOfFirstMessageStart,
                        (indexOfEndOfFirstMessageEndWithinEntireMessageBuffer - indexOfFirstMessageStart));


                    //string[] delimeters = new string[] { CrossPlatformConstants.simpleStringDelimeterForMessages };
                    string[] parts = firstMessage.Split(CrossPlatformConstants.simpleStringDelimeterForMessages);
                    if (parts.Length == 4)
                    {
                        int raw = int.Parse(parts[1]);
                        int calibrated = int.Parse(parts[2]);
                        RawDistanceCentimeters = raw;
                        CalibratedWaterLevelCentimeters = calibrated;
                        successParsing = true;
                        if (removeParsedMessage)
                        {
                            string beforeParsedMessage = currentMessage.Substring(0, indexOfFirstMessageStart);
                            string afterParsedMessage = currentMessage.Substring(indexOfEndOfFirstMessageEndWithinEntireMessageBuffer);
                            messageBufferWithMessageRemoved = beforeParsedMessage + afterParsedMessage;
                        }
                    }
                }
            }
            //}
            //catch (System.Exception)
            //{
            //    successParsing = false; // fail on unknown exception
            //}
            return messageBufferWithMessageRemoved;
        }

        public string createSumpPumpEventMessage(DateTime EventTime, string eventType, string eventDescription)
        {
            string newMessage = SumpPumpEventMessageStartString
                + CrossPlatformConstants.simpleStringDelimeterForMessages
                + EventTime.ToString()
                + CrossPlatformConstants.simpleStringDelimeterForMessages
                + eventType
                + CrossPlatformConstants.simpleStringDelimeterForMessages
                + eventDescription
                + CrossPlatformConstants.simpleStringDelimeterForMessages
                + SumpPumpEventMessageEndString;
            return newMessage;
        }

        public string parseSumpPumpEventMessage(
            string currentMessage,
            ref bool successParsing,
            ref string EventTime,
            ref string eventType,
            ref string eventDescription,
            bool removeParsedMessage)
        {
            string messageBufferWithMessageRemoved = currentMessage;
            successParsing = false; // default to fail

            // find start of a message (in case there are multiple messages or a partial message)
            string firstMessage = string.Empty;
            int indexOfFirstMessageStart = currentMessage.IndexOf(SumpPumpEventMessageStartString);

            // if we found a start of a message, try to parse it
            if (indexOfFirstMessageStart >= 0)
            {
                firstMessage = currentMessage.Substring(indexOfFirstMessageStart);

                // now try to find a message end that completes the first message
                int indexOfStartOfFirstMessageEndWithinFirstMessage = firstMessage.IndexOf(SumpPumpEventMessageEndString);
                if (indexOfStartOfFirstMessageEndWithinFirstMessage >= 0)
                {
                    // calculate end of message end tag within entire message buffer
                    int indexOfEndOfFirstMessageEndWithinEntireMessageBuffer = indexOfFirstMessageStart + indexOfStartOfFirstMessageEndWithinFirstMessage + SumpPumpEventMessageEndString.Length;

                    firstMessage = currentMessage.Substring(indexOfFirstMessageStart,
                        (indexOfEndOfFirstMessageEndWithinEntireMessageBuffer - indexOfFirstMessageStart));


                    //string[] delimeters = new string[] { CrossPlatformConstants.simpleStringDelimeterForMessages };
                    string[] parts = firstMessage.Split(CrossPlatformConstants.simpleStringDelimeterForMessages);
                    if (parts.Length == 5)
                    {
                        EventTime = parts[1];
                        eventType = parts[2];
                        eventDescription = parts[3];
                        successParsing = true;
                        if (removeParsedMessage)
                        {
                            string beforeParsedMessage = currentMessage.Substring(0, indexOfFirstMessageStart);
                            string afterParsedMessage = currentMessage.Substring(indexOfEndOfFirstMessageEndWithinEntireMessageBuffer);
                            messageBufferWithMessageRemoved = beforeParsedMessage + afterParsedMessage;
                        }
                    }

                }
            }
            //}
            //catch (System.Exception)
            //{
            //    successParsing = false; // fail on unknown exception
            //}
            return messageBufferWithMessageRemoved;
        }
    }

    class NetControlToolsMessage
    {
        static string MessageIdentifier = CrossPlatformConstants.NetControlToolsMessageIdentifier;
    }

    class SensorMessage : NetControlToolsMessage
    {
        static string SensorMessageTestString = "Sensor Message Test String";
    }

    class DoorContactMessage : SensorMessage
    {
        static string DoorContactMessageTestString = "Door Contact Message Test String";
    }
}
